package 线程池.CompletableFuture;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author: wh(1835734390 @ qq.com)
 * @date: 2023/4/24 14:31
 * @description:多组合任务
 * @version:
 */
public class ShowThread8 {
    //创建线程池  第一个参数代表核心线程数
    public static ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main....start....");

        CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的图片信息");
            return "hello.jpg";
        }, executor);

        CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("查询商品的属性信息");
            return "黑色+256G";
        }, executor);

        CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品介绍");
            return "华为Mate40 Pro";
        }, executor);


        //按照正常的写法是通过 get()，等上一个任务执行完，再执行下一个，一次类推
        //但这样是相当耗时的，假设第一个任务执行需要10s，那么后面所有的任务都需要等待10s
//        futureImg.get();
//        futureAttr.get();
//        futureDesc.get();

        //在JDK8我们可以使用  CompletableFuture.allOf();
        CompletableFuture<Void> future = CompletableFuture.allOf(futureImg,futureAttr,futureDesc);

        //任一任务完成执行
//        CompletableFuture<Void> future = CompletableFuture.anyOf(futureImg,futureAttr,futureDesc);

        //等待所有线程的结果完成
        future.get();//输出结果可以看到，只有等三个线程执行完后才输出的 main...end..

        //但如果我们不调用 future.get() 方法，我们可以发现 main...end.. 并不是最后输出的
        //为了效果明显，我们可以在线程2中加上睡眠3s

        System.out.println("main....end....");
        executor.shutdown();
    }
}
